package com.xu.modules.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xu.common.consts.XuConst;
import com.xu.common.enums.ArticleNumTypeEnum;
import com.xu.common.enums.StationNumTypeEnum;
import com.xu.common.utils.TokenUtil;
import com.xu.modules.entity.CommentEntity;
import com.xu.modules.mapper.CommentMapper;
import com.xu.modules.service.ArticleService;
import com.xu.modules.service.CommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xu.modules.service.PersonalUserService;
import com.xu.modules.service.StationService;
import com.xu.modules.service.bo.CommentBo;
import com.xu.modules.service.vo.CommentVo;
import com.xu.modules.service.vo.PersonalUserVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 评论 服务实现类
 * </p>
 *
 * @author xu
 * @since 2022-07-26
 */
@Service
@RequiredArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentEntity> implements CommentService {
    private final TokenUtil tokenUtil;
    private final CommentMapper commentMapper;
    private final ArticleService articleService;
    private final PersonalUserService personalUserService;
    private final StationService stationService;

    @Override
    public List<CommentVo> listByArticle(Long articleId) {
        LambdaQueryWrapper<CommentEntity> lqw = Wrappers.lambdaQuery();
        lqw.eq(CommentEntity::getArticleId,articleId);
        // 查询出评论列表
        List<CommentEntity> commentEntityList = commentMapper.selectList(lqw);
        // 如果为空就返回空集合
        if(CollectionUtils.isEmpty(commentEntityList)){
            return Collections.emptyList();
        }
        // 查询所有用户
        List<PersonalUserVo> personalUserVoList = personalUserService.listAll();
        // 评论转
        List<CommentVo> commentVoList = BeanUtil.copyToList(commentEntityList, CommentVo.class);
        commentVoList.forEach(commentVo->{
            for (PersonalUserVo userVo : personalUserVoList) {
                // 匹配用户
                if(userVo.getUserId().equals(commentVo.getUserId())){
                    commentVo.setNickname(userVo.getNickname());
                }
                if(userVo.getUserId().equals(commentVo.getReplyUserId())){
                    commentVo.setReplyNickname(userVo.getNickname());
                }
            }

        });
        // 转成树形结构
        return transToTree(commentVoList);
    }

    @Override
    public void add(CommentBo commentBo) {
        // 先获取个人信息
        PersonalUserVo personalUserVo = tokenUtil.getUserInfo();
        // 初始化信息
        CommentEntity commentEntity = BeanUtil.copyProperties(commentBo, CommentEntity.class);
        // 设置个人信息
        commentEntity.setUserId(personalUserVo.getUserId());
        // 插入
        commentMapper.insert(commentEntity);
        // 再设置数量
        if(!XuConst.THE_STATION_ARTICLE_ID.equals(commentBo.getArticleId())){ // 如果不是本站
            articleService.addArticleNum(commentBo.getArticleId(), ArticleNumTypeEnum.COMMENT);
        }
        stationService.changeStationNum(StationNumTypeEnum.COMMENT);
    }

    /**
     * 将评论集合转为树形结构
     */
    public static List<CommentVo> transToTree(List<CommentVo> voList) {
        if (CollectionUtils.isEmpty(voList)) {
            return Collections.emptyList();
        }
        // 将评论ID作为一个对象的标识
        Map<Long, CommentVo> sourceMap = voList.stream().collect(Collectors.toMap(CommentVo::getCommentId, e -> e));
        // 将整个集合根据父ID进行分组
        Map<Long, List<CommentVo>> pIdToChildrenListMap = voList.stream().collect(Collectors.groupingBy(CommentVo::getPid));
        // 父ID集合
        List<Long> willBeRemovedIdList = new LinkedList<>();
        // 遍历所有父ID
        for (Map.Entry<Long, List<CommentVo>> entry : pIdToChildrenListMap.entrySet()) {
            CommentVo commentVo = sourceMap.get(entry.getKey());
            // 如果父ID 没有评论 就不是子评论 下一个
            if (commentVo == null) {
                continue;
            }
            // 为父评论 设置所有的子评论
            commentVo.setReplyList(new ArrayList<>(entry.getValue()));
            // 记录父ID
            willBeRemovedIdList.add(entry.getKey());
        }
        willBeRemovedIdList.forEach(pIdToChildrenListMap::remove);
        // 获取顶级 加上排序
        return pIdToChildrenListMap
                .values()
                .stream()
                .flatMap(Collection::stream)
                .sorted(Comparator.comparing(CommentVo::getCreateTime).reversed())
                .collect(Collectors.toList());
    }
}
